package com.vcredit.creditcat.service.resource;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.vcredit.creditcat.dto.resource.ResourceDto;
import com.vcredit.creditcat.enumtype.ResourceTypeEnum;
import com.vcredit.creditcat.exception.ResourceException;
import com.vcredit.creditcat.model.SysResource;
import com.vcredit.creditcat.service.SysResourceService;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.EnumExtUtil;
import com.vcredit.framework.util.FtpUtil;
import com.vcredit.framework.util.MD5Util;

@Service
public class FtpResourceService{

  @Value("${ftp.address}")
  private String ftpAddress;
  @Value("${ftp.port}")
  private String ftpPort;
  @Value("${ftp.userName}")
  private String ftpUserName;
  @Value("${ftp.password}")
  private String ftpPassword;
  @Value("${resource.path}")
  private String resourcePath;

  @Autowired
  private SysResourceService sysResourceService;

  public ResourceDto upload(ResourceTypeEnum resourceType, String fileName, byte[] fileByte)
      throws ResourceException {
    FTPClient ftpLogin = null;
    try {
      if (!resourcePath.endsWith("/")) {
        resourcePath += "/";
      }
      String date = ConcurrentDateUtil.format(new Date(), "yyyyMMdd");
      Long timestp = new Date().getTime();
      String absolutePath =
          StringUtils
              .join(
                  new ArrayList<String>(Arrays.asList(resourcePath, resourceType.getDesc(), date)),
                  "/");
      String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
      String code = MD5Util.encode(String.valueOf((fileName + timestp).hashCode())).toUpperCase();
      String newFileName = code + fileSuffix;
      // ftp连接并登陆
      ftpLogin = FtpUtil.connectFtp(ftpAddress, Integer.valueOf(ftpPort), ftpUserName, ftpPassword);
      ftpLogin.makeDirectory(absolutePath);
      ftpLogin.changeWorkingDirectory(absolutePath);
      // 上传文件
      ftpLogin.storeFile(newFileName, new ByteArrayInputStream(fileByte));
      String relativeUrl =
          StringUtils.join(
              new ArrayList<String>(Arrays.asList(resourceType.getDesc(), date, newFileName)), "/");// 相对路径
      Long resourceId =
          sysResourceService.insert(new SysResource(code, resourceType.getCode(), fileName,
              relativeUrl));

      return new ResourceDto(resourceId, resourceType, code, fileByte);
    } catch (Exception e) {
      throw new ResourceException("文件保存失败");
    } finally {
      fileByte = null;
      try {
        ftpLogin.disconnect();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  public ResourceDto download(String code) throws ResourceException {

    List<SysResource> resources = sysResourceService.find(new SysResource(code));

    return downloadSysResource(resources);
  }

  private ResourceDto downloadSysResource(List<SysResource> resources) throws ResourceException {
    if (resources.size() == 0) {
      throw new ResourceException("资源未找到");
    }

    InputStream input = null;
    FTPClient ftpClient = null;
    try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
      SysResource sysResource = resources.get(0);
      String filePath = sysResource.getOriginalSavepath();
      ResourceTypeEnum eResourceTypeEnum =
          EnumExtUtil.getEnumOnValue(ResourceTypeEnum.class,
              String.valueOf(sysResource.getResourceType()), "code");
      if (eResourceTypeEnum == null) {
        throw new ResourceException("资源未找到");
      }

      // ftp下载资源
      ftpClient =
          FtpUtil.connectFtp(ftpAddress, Integer.valueOf(ftpPort), ftpUserName, ftpPassword);
      input = ftpClient.retrieveFileStream(resourcePath + filePath);
      if (input == null) {
        throw new ResourceException("资源未找到");
      }
      byte[] buffer = new byte[4096];
      int n = 0;
      while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
      }
      return new ResourceDto(sysResource.getResourceId(), eResourceTypeEnum,
          sysResource.getResourceCode(), output.toByteArray());
    } catch (Exception ex) {
      ex.printStackTrace();
      throw new ResourceException(ex.getMessage());
    } finally {
      try {
        if (null != ftpClient) {
          ftpClient.disconnect();
          ftpClient = null;
        }
        if (null != input) {
          input.close();
          input = null;
        }
      } catch (Exception e) {
        e.printStackTrace();
        throw new ResourceException(e.getMessage());
      }
    }
  }

}
